<template>
  <div>
    <el-button type="success" size='small' @click="routeConfig(1)" class="ripConfigClick">{{$t('路由配置')}}</el-button>
    <el-button type="danger" size='small' @click="routeConfig(2)" class="ripShowClick">{{$t('路由展示')}}</el-button>
    <el-button type="success" size='small' @click="reloadRip()" icon="el-icon-refresh" v-if="showConfig === 1" class="ripReClick">{{$t('重载配置')}}</el-button>
    <el-descriptions title="" size="small" :column='1' border contentClassName='ripContentDescriptions' labelClassName='ripContentDescriptions' style="margin-top:20px;" v-if="showConfig === 1" class="ripDescriptions">
      <el-descriptions-item :label="$t('RIP状态')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <el-switch :width="lang === 'zh'?56:70" v-model="record.status" style="margin-left: 15px;" class="ripSwitch switch" active-color="#009966" inactive-color="#CCCCCC" active-value="on" inactive-value="off" @change="statusChange" :active-text="$t('开启')" :inactive-text="$t('关闭')"></el-switch>
      </el-descriptions-item>
      <el-descriptions-item :label="$t('开启RIP协议的网段')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">{{$t('开启RIP协议的网段')}}
          <el-tooltip class="item" effect="light" :content="$t('提示信息：用来发布接口上具体的Ipv4地址')" placement="top">
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        <el-select v-model="record.net" ref="ripNet" :placeholder="$t('请选择')" multiple filterable allow-create default-first-option @change="changeSelect" size='small' style="width:500px;">
          <div class="selectBox">
            <el-link icon='el-icon-finished' :underline="false" type="primary" @click='selectAll'>{{$t('全选')}}</el-link>
          </div>
          <el-option v-for="item in netList" :key="item.label" :label="item.label" :value="item.label">
          </el-option>
        </el-select>
      </el-descriptions-item>
      <el-descriptions-item :label="$t('开启被动状态的接口')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">{{$t('开启被动状态的接口')}}
          <el-tooltip class="item" effect="light" :content="$t('提示信息:接口处于被动状态时，只接收处理Rip报文，不发送单播、多播Rip报文')" placement="top">
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        <el-select v-model="record.interface_name" ref="ripInterfaceName" :placeholder="$t('请选择')" multiple filterable @change="interfaceNameChange" size='small' style="width:500px;">
          <el-option v-for="item in policyList" :key="item.name" :label="item.name" :value="item.name" :disabled='policyDisabled(item)'>
          </el-option>
        </el-select>
      </el-descriptions-item>
      <el-descriptions-item :label="$t('开启RIP协议的接口')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">{{$t('开启RIP协议的接口')}}
          <el-tooltip class="item" effect="light" :content="$t('提示信息：用来发布接口上所有的Ipv4地址；且要添加直连口，用来实现RIP协议通信')" placement="top">
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        <el-select v-model="record.ifname" ref="ripIfname" :placeholder="$t('请选择')" multiple filterable @change="ifnameChange" value-key="id" size='small' style="width:500px;">
          <el-option v-for="item in policyList" :key="item.name" :label="item.name" :value="item.name" :disabled='policyDisabled(item)'>
          </el-option>
        </el-select>
      </el-descriptions-item>
      <el-descriptions-item :label="$t('RIP协议的版本')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">{{$t('RIP协议的版本')}}
          <el-tooltip class="item" effect="light" :content="$t('提示信息:默认发送版本为2，接收版本1、2都支持。开启接口认证时，要使用RIPv2')" placement="top">
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        <el-radio-group v-model="record.version" size='small' @change="versionChange">
          <el-radio label="1" class="ripRipv1">RIPv1</el-radio>
          <el-radio label="2" class="ripRipv2">RIPv2</el-radio>
          <el-radio label="default" class="ripDefault">{{$t('默认')}}</el-radio>
        </el-radio-group>
      </el-descriptions-item>
      <!-- <el-descriptions-item label="RIP协议distance" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">RIP协议distance
          <el-tooltip class="item" effect="light" :content="$t('提示信息:无符号整数，1-255，默认值120，输入框失去焦点后自动提交')" placement="top">
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        <el-input v-emoji v-model="record.distance" style="width:500px;" size='small' @focus="distanceFocus" @blur="distanceBlur"></el-input>
      </el-descriptions-item> -->
      <el-descriptions-item :label="$t('RIP协议定时器')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <template slot="label">{{$t('RIP协议定时器')}}
          <el-tooltip class="item" effect="light" placement="top">
            <div slot="content">{{$t('提示信息')}}<br />{{$t('update:无符号整数，5-3600，默认值30秒')}}<br />{{$t('timeout:无符号整数，5-3600，默认值180秒')}}</div>
            <i class="el-icon-warning-outline" style="color:#666;font-size:14px;"></i>
          </el-tooltip>
        </template>
        update
        <el-input v-emoji v-model="record.update" ref="ripUpdate" style="width:200px;margin:0 20px 0 10px;" size='small' @blur="timeChange('update')"></el-input>
        timeout
        <el-input v-emoji v-model="record.timeout" ref="ripTimeout" style="width:200px;margin:0 20px 0 10px;" size='small' @blur="timeChange('timeout')"></el-input>
        <!-- <el-button type="success" size='small' @click="timeChange">{{$t('修改定时器')}}</el-button> -->
      </el-descriptions-item>
      <el-descriptions-item :label="$t('RIP接口配置')" :labelStyle="{ 'text-align': 'left', 'width': '210px', 'line-height': '35px' }">
        <el-button type="success" size='small' @click="dialogVisible()" class="ripAddConfig">{{$t('新增配置')}}</el-button>
        <el-table size='small' ref="multipleConfigTable" :data="ripConfigList" tooltip-effect="dark" style="width: 100%;">
          <el-table-column prop="ifname" :label="$t('接口名称')" align='center' min-width="100"></el-table-column>
          <el-table-column prop="mode" :label="$t('认证方式')" align='center' min-width="100">
            <template slot-scope="scope">
              {{ modeList[scope.row.mode] }}
            </template>
          </el-table-column>
          <el-table-column prop="split_horizon_status" :label="$t('水平分割')" align='center' min-width="100">
            <template slot-scope="scope">
              {{ splitHorizonStatusList[scope.row.split_horizon_status] }}
            </template>
          </el-table-column>
          <el-table-column prop="right" align='center' fixed="right" :label="$t('操作')" :width="lang === 'zh'?'150':'160'">
            <template slot-scope="scope">
              <el-button type="success" plain size="mini" @click="dialogVisible(scope.row, '编辑')" :class="'ripEdit' +(scope.$index+1)">{{$t('编辑')}}</el-button>
              <el-button type="danger" plain size="mini" @click="deleteData(scope.row)" :class="'ripDel' +(scope.$index+1)">{{$t('删除')}}</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-descriptions-item>
    </el-descriptions>
    <el-table size='small' ref="multipleTable" :data="tableList" tooltip-effect="dark" style="width: 100%;margin-top:20px;" v-if="showConfig === 2">
      <el-table-column prop="destination" :label="$t('目的地址')" align='center' min-width="200"></el-table-column>
      <el-table-column prop="next_hop" :label="$t('下一跳')" align='center' min-width="200"></el-table-column>
      <el-table-column prop="out_interface" :label="$t('出接口')" align='center' min-width="200"></el-table-column>
    </el-table>
    <rip-dialog v-if="ripDialogVisible" ref="refRipDialogVisible"></rip-dialog>
  </div>
</template>

<script>
import { getPhysicalApiArray } from '@/api/network/api/physical'
import { getVirtualApiArray } from '@/api/network/api/virtual'
import RipDialog from './RipDialog'
import {
  getRipTimers, // RIP获取定时器
  setRipTimers, // RIP设置定时器
  getRipDistance, // RIP获取distance
  setRipDistance, // RIP设置distance
  getRipVersion, // RIP获取协议版本
  setRipVersion, // RIP设置协议版本
  getRipInterface, // RIP获取开启RIP的接口
  addRipInterface, // RIP增加开启RIP的接口
  delRipInterface, // RIP删除开启RIP的接口
  getRipNet, // RIP获取开启的网段
  addRipNet, // RIP增加开启的网段
  delRipNet, // RIP删除开启的网段
  getRipPassiveInterface, // RIP获取开启被动状态的接口
  addRipPassiveInterface, // RIP增加开启被动状态的接口
  delRipPassiveInterface, // RIP删除开启被动状态的接口
  getRipRoute, // RIP获取路由
  getRipIfconfig, // RIP获取接口配置信息
  delRipIfconfig, // RIP删除接口配置信息
  getRipStatus, // RIP获取状态
  setRipStatus, // RIP设置状态
  reloadAgreement // 协议重载
} from '@/api/network/route/dynamicRoute/RIP'
import { inputClass, selectClass } from '@/utils/input-class.js'
export default {
  name: 'RIP',
  components: {
    RipDialog
  },
  data () {
    return {
      ripDialogVisible: false,
      record: {
        status: 'off',
        net: [],
        old_net: [],
        ifname: [],
        old_ifname: [],
        interface_name: [],
        old_interface_name: [],
        version: '2',
        distance: '',
        update: '',
        timeout: '',
        garbage: '120',
        update_old: '',
        timeout_old: ''
      },
      old_distance: '',
      showConfig: 1,
      netList: [],
      netListAll: [],
      policyList: [],
      policyListAll: [],
      tableList: [],
      ripConfigList: [],
      lang: this.$i18n.locale,
      splitHorizonStatusList: {
        'off': this.$t('关闭'),
        'on': this.$t('开启')
      },
      modeList: {
        'md5': 'MD5',
        'text': this.$t('简单密码'),
        'off': this.$t('关闭')
      }
    }
  },
  mounted () {
    this.$nextTick(() => {
      const data = ['ripUpdate', 'ripTimeout']
      const selectData = ['ripNet', 'ripInterfaceName', 'ripIfname']
      inputClass(this.$refs, data)
      selectClass(this.$refs, selectData)
    })
  },
  methods: {
    listData () {
      this.showConfig = 1
      getPhysicalApiArray().then(res => {
        if (res.status === 0) {
          getVirtualApiArray({page: 1, limit: 4086}).then(response => {
            if (response.status === 0) {
              this.policyList = []
              this.netList = []
              this.netListAll = []
              for (let item of res.info) {
                item.name = item.strPhysicsName
                this.policyList.push(item)
                if (item.enPortMode === 0) {
                  // 网段下拉框内容
                  for (let item1 of item.ipv4) {
                    if (item1.cPortIpv4) {
                      const label = this.netIframe(item1.cPortIpv4, item.strPhysicsName, item1.cPortNetmask)
                      if (!this.netList.some(v => v.label === label)) {
                        this.netList.push({ label: label })
                        this.netListAll.push(label)
                      }
                    }
                  }
                }
              }
              for (let item1 of response.info) {
                item1.name = item1.strBridgeName
                this.policyList.push(item1)
              }
              this.getRipNetData()
            }
          })
        }
      })
      getRipStatus().then(res => {
        if (res.status === 0) {
          this.record.status = res.info[0].status
        }
      })
      getRipPassiveInterface().then(res => {
        if (res.status === 0) {
          this.record.interface_name = []
          this.record.old_interface_name = []
          for (let item of res.info) {
            this.record.interface_name.push(item.ifname)
            this.record.old_interface_name.push(item.ifname)
          }
        }
      })
      getRipInterface().then(res => {
        if (res.status === 0) {
          this.record.ifname = []
          this.record.old_ifname = []
          for (let item of res.info) {
            this.record.ifname.push(item.ifname)
            this.record.old_ifname.push(item.ifname)
          }
        }
      })
      getRipDistance().then(res => {
        if (res.status === 0) {
          this.record.distance = res.info[0].distance
        }
      })
      getRipVersion().then(res => {
        if (res.status === 0) {
          this.record.version = res.info[0].version
        }
      })
      getRipTimers().then(res => {
        if (res.status === 0) {
          this.record.update = res.info[0].update
          this.record.timeout = res.info[0].timeout
          this.record.update_old = res.info[0].update
          this.record.timeout_old = res.info[0].timeout
        }
      })
      getRipIfconfig().then(res => {
        if (res.status === 0) {
          this.ripConfigList = res.info
        }
      })
    },
    getRipNetData () {
      getRipNet().then(res => {
        this.record.net = []
        this.record.old_net = []
        for (let item of res.info) {
          let netList = this.netListAll.filter(v => v.indexOf(item.net) > -1)
          this.record.net = this.record.net.concat(netList)
          this.record.old_net = this.record.old_net.concat(netList)
        }
      })
    },
    ripConfigListInfo () {
      getRipIfconfig().then(res => {
        if (res.status === 0) {
          this.ripConfigList = res.info
        }
      })
    },
    selectAll () {
      let set = this.arrayFind(this.netListAll, this.record.net).map(v => { return v.split('-')[0] })
      set = Array.from(new Set(set))
      let flag = set.length || 0
      set.forEach((item) => {
        // this.record.net.push(item)
        addRipNet({ net: item }).then(() => {
          flag -= 1
          if (flag === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.getRipNetData()
          }
        })
      })
      // this.record.old_net = this.record.net
    },
    // 开启RIP协议的网段
    changeSelect (val) {
      if (val.length > this.record.old_net.length) {
        addRipNet({ net: Array.from(new Set(this.arrayFind(val, this.record.old_net).map(item => { return item.split('-')[0] }))) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_net = val
          } else {
            this.record.net = this.record.old_net
          }
          this.getRipNetData()
        }).catch(e => {
          this.getRipNetData()
        })
      } else {
        delRipNet({ net: Array.from(new Set(this.arrayFind(this.record.old_net, val).map(item => { return item.split('-')[0] }))) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_net = val
          } else {
            this.record.net = this.record.old_net
          }
          this.getRipNetData()
        }).catch(e => {
          this.getRipNetData()
        })
      }
    },
    // 开启被动状态的接口
    interfaceNameChange (val) {
      if (val.length > this.record.old_interface_name.length) {
        addRipPassiveInterface({ interface_name: this.arrayFind(val, this.record.old_interface_name) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_interface_name = val
          } else {
            this.record.interface_name = this.record.old_interface_name
          }
        }).catch(e => {
          getRipPassiveInterface().then(res => {
            if (res.status === 0) {
              this.record.interface_name = []
              this.record.old_interface_name = []
              for (let item of res.info) {
                this.record.interface_name.push(item.ifname)
                this.record.old_interface_name.push(item.ifname)
              }
            }
          })
        })
      } else {
        delRipPassiveInterface({ ifname: this.arrayFind(this.record.old_interface_name, val) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_interface_name = val
          } else {
            this.record.interface_name = this.record.old_interface_name
          }
        }).catch(e => {
          getRipPassiveInterface().then(res => {
            if (res.status === 0) {
              this.record.interface_name = []
              this.record.old_interface_name = []
              for (let item of res.info) {
                this.record.interface_name.push(item.ifname)
                this.record.old_interface_name.push(item.ifname)
              }
            }
          })
        })
      }
    },
    // 开启RIP协议的接口
    ifnameChange (val) {
      if (val.length > this.record.old_ifname.length) {
        addRipInterface({ ifname: this.arrayFind(val, this.record.old_ifname) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_ifname = val
          } else {
            this.record.ifname = this.record.old_ifname
          }
        }).catch(e => {
          getRipInterface().then(res => {
            if (res.status === 0) {
              this.record.ifname = []
              this.record.old_ifname = []
              for (let item of res.info) {
                this.record.ifname.push(item.ifname)
                this.record.old_ifname.push(item.ifname)
              }
            }
          })
        })
      } else {
        delRipInterface({ ifname: this.arrayFind(this.record.old_ifname, val) }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            this.record.old_ifname = val
          } else {
            this.record.ifname = this.record.old_ifname
          }
        }).catch(e => {
          getRipInterface().then(res => {
            if (res.status === 0) {
              this.record.ifname = []
              this.record.old_ifname = []
              for (let item of res.info) {
                this.record.ifname.push(item.ifname)
                this.record.old_ifname.push(item.ifname)
              }
            }
          })
        })
      }
    },
    policyDisabled (row) {
      return !(row.enPortMode === 0 && row.ipv4 && row.ipv4[0].cPortIpv4)
    },
    routeConfig (data) {
      this.showConfig = data
      if (data === 2) {
        getRipRoute().then(res => {
          if (res.status === 0) {
            this.tableList = res.info
          }
        })
      }
    },
    // 找两个数组的不同
    arrayFind (arrA, arrB) {
      return arrA.filter(v => !arrB.includes(v))
    },
    // 整理网段下拉框内容
    netIframe (data, api, mask) {
      let str = ''
      // 把ip和掩码转换成二进制
      const binaryIP = data.split('.').map(segment => parseInt(segment).toString(2).padStart(8, '0')).join('')
      const binaryMask = mask.split('.').map(segment => parseInt(segment).toString(2).padStart(8, '0')).join('')
      // 进行与操作获取子网
      let networkAddress = ''
      for (let i = 0; i < binaryIP.length; i++) {
        if (binaryMask[i] === '1') {
          networkAddress += binaryIP[i]
        } else {
          networkAddress += '0'
        }
      }
      // 分割子网8位一组
      let netGroup = networkAddress.match(/.{1,8}/g)
      let subnet = ''
      for (let index in netGroup) {
        if (index !== '0') {
          subnet += '.'
        }
        subnet += parseInt(netGroup[index], 2)
      }
      // 计算掩码位数
      const maskLength = binaryMask.indexOf('0') === -1 ? 32 : binaryMask.indexOf('0')
      str = subnet + '/' + maskLength + '-' + api
      return str
    },
    timeChange (name) {
      if (String(this.record[name]) !== String(this.record[name + '_old'])) {
        if (!this.isInteger(this.record.update) && String(this.record.update).trim() !== '') {
          this.$messages.error(this.$t('update定时器必须是无符号整数'))
        } else if (!this.isInteger(this.record.timeout) && String(this.record.timeout).trim() !== '') {
          this.$messages.error(this.$t('timeout定时器必须是无符号整数'))
        } else if ((Number(this.record.update) < 5 || Number(this.record.update) > 3600) && String(this.record.update).trim() !== '') {
          this.$messages.error(this.$t('输入的update定时器无效，范围是5-3600'))
        } else if ((Number(this.record.timeout) < 5 || Number(this.record.timeout) > 3600) && String(this.record.timeout).trim() !== '') {
          this.$messages.error(this.$t('输入的timeout定时器无效，范围是5-3600'))
        } else {
          setRipTimers({ update: this.record.update, timeout: this.record.timeout, garbage: this.record.garbage }).then(res => {
            this.$messages.success(this.$t('执行成功'))
            this.record[name + '_old'] = this.record[name]
            if (this.record.update === '') {
              this.record.update = 30
            }
            if (this.record.timeout === '') {
              this.record.timeout = 180
            }
          })
        }
      }
    },
    distanceFocus () {
      this.old_distance = this.record.distance
    },
    // RIP协议distance
    distanceBlur () {
      if (this.old_distance !== this.record.distance) {
        setRipDistance({ distance: this.record.distance }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('执行成功'))
            getRipDistance().then(res => {
              if (res.status === 0) {
                this.record.distance = res.info[0].distance
              }
            })
          }
        })
      }
    },
    // RIP协议的版本
    versionChange () {
      setRipVersion({ version: this.record.version }).then(res => {
        if (res.status === 0) {
          this.$messages.success(this.$t('执行成功'))
        }
      }).catch(e => {
        getRipVersion().then(res => {
          if (res.status === 0) {
            this.record.version = res.info[0].version
          }
        })
      })
    },
    // RIP状态
    statusChange () {
      setRipStatus({ status: this.record.status }).then(res => {
        if (res.status === 0) {
          this.$messages.success(this.$t('执行成功'))
        }
      }).catch(e => {
        getRipStatus().then(res => {
          if (res.status === 0) {
            this.record.status = res.info[0].status
          }
        })
      })
    },
    dialogVisible (data, type) {
      this.ripDialogVisible = true
      this.$nextTick(() => {
        this.$refs.refRipDialogVisible.init(data, type)
      })
    },
    deleteData (data) {
      this.$confirm(this.$t('您是否要删除所选中的数据？'), this.$t('提示'), {
        closeOnClickModal: false,
        confirmButtonText: this.$t('确定'),
        cancelButtonText: this.$t('取消'),
        confirmButtonClass: 'confirmButton',
        cancelButtonClass: 'confirmCancelButton',
        type: 'warning'
      }).then(() => {
        delRipIfconfig({ ifname: data.ifname }).then(res => {
          if (res.status === 0) {
            this.$messages.success(this.$t('删除成功'))
            getRipIfconfig().then(res => {
              if (res.status === 0) {
                this.ripConfigList = res.info
              }
            })
          }
        })
      })
    },
    reloadRip () {
      reloadAgreement({ agreement: 'rip' }).then(res => {
        if (res.status === 0) {
          this.listData()
          this.$messages.success(this.$t('重载成功'))
        }
      })
    },
    isInteger (value) {
      return (!isNaN(value) && (parseInt(value).toString().length === String(Number(value)).length))
    }
  }
}
</script>

<style lang="less" scoped>
.selectBox {
  padding: 0 20px;
}
</style>
